from libs.lex import *
from libs.execute import *
from libs.units import *

def ast(tokens: list):
    if type(tokens) == Token:
        if tokens.type == TokenValueType.LETTER:
            return [ConstantUnit(tokens.value, TokenValueType.SYMBOL)]
        return [ConstantUnit(tokens.value, tokens.type)]
    elif len(tokens) == 1:
        if tokens[0].type == TokenValueType.LETTER:
            return [ConstantUnit(tokens[0].value, TokenValueType.SYMBOL)]
        return [ConstantUnit(tokens[0].value, tokens[0].type)]
    result = []
    seek = 0
    tokens_size = len(tokens)
    while seek < tokens_size:
        if tokens[seek].type == TokenValueType.OPERATOR:
            left = tokens[seek-1]
            operator = tokens[seek]
            right = []
            while seek+1 < tokens_size and tokens[seek+1].type != TokenValueType.TERMINAL:
                right.append(tokens[seek+1])
                seek+=1
            if operator.value == "=":
                assert left.type == TokenValueType.LETTER, f"Syntax Error: {left.value} must be a string!"
                result.append(AssignmentUnit(ast(left)[0], ast(right)[0]))
            elif operator.value == "+":
                result.append(AddUnit(ast(left)[0], ast(right)[0]))
            elif operator.value == "-":
                result.append(SubUnit(ast(left)[0], ast(right)[0]))
            elif operator.value == "*":
                result.append(MulUnit(ast(left)[0], ast(right)[0]))
            elif operator.value == "/":
                result.append(DivUnit(ast(left)[0], ast(right)[0]))
        seek+=1
    return result

def print_lex(tokens:list):
    for i in tokens:
        print(str(i), end="")
    
# lexed = lex(TokenSwitcher.lex_token("x=109/4;"))
lexed = Lex().lex("x=1;y=x*2;")
print_lex(lexed)
executer = Execute()
ast_tree = ast(lexed)
executer.execute(ast_tree)
print(executer.symbol_table.table['y'].value)